package org.origin.centre.support.utils;

import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Servlet 工具类
 *
 * @author ferret
 * @version 2024-05-08
 */
@SuppressWarnings("unused")
public final class ServletUtil {

    /**
     * 获取网络请求 HttpSession
     *
     * @return HttpServletRequest
     */
    public static HttpSession getSession() {
        HttpServletRequest request = getAttributes().getRequest();
        return request.getSession();
    }

    /**
     * 获取网络请求
     *
     * @return HttpServletRequest
     */
    public static HttpServletRequest getRequest() {
        return getAttributes().getRequest();
    }

    /**
     * 获取网络请求响应
     *
     * @return HttpServletResponse
     */
    public static HttpServletResponse getResponse() {
        return getAttributes().getResponse();
    }

    /**
     * 获取 Attributes
     *
     * @return ServletRequestAttributes
     */
    private static ServletRequestAttributes getAttributes() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes instanceof ServletRequestAttributes) {
            return (ServletRequestAttributes) requestAttributes;
        }
        throw new IllegalArgumentException("请求为非客户端请求");
    }

    /**
     * 写入成功返回
     */
    public static void writeSuccess(HttpServletResponse resp, byte[] bytes) throws Exception {
        ServletOutputStream os = null;
        try {
            os = resp.getOutputStream();
            resp.setStatus(HttpStatus.OK.value());
            os.write(bytes);
            os.flush();
        } finally {
            close(os);
        }
    }

    /**
     * 写入成功返回
     */
    public static void writeSuccess(HttpServletResponse resp, ServletOutputStream os, byte[] bytes) throws Exception {
        try {
            resp.setStatus(HttpStatus.OK.value());
            os.write(bytes);
            os.flush();
        } finally {
            close(os);
        }
    }

    /**
     * 写入错误返回
     */
    public static void writeError(HttpServletResponse resp, byte[] bytes) throws Exception {
        ServletOutputStream os = null;
        try {
            os = resp.getOutputStream();
            resp.setStatus(HttpStatus.BAD_REQUEST.value());
            os.write(bytes);
            os.flush();
        } finally {
            close(os);
        }
    }

    /**
     * 写入错误返回
     */
    public static void writeError(HttpServletResponse resp, ServletOutputStream os, byte[] bytes) throws Exception {
        try {
            resp.setStatus(HttpStatus.BAD_REQUEST.value());
            os.write(bytes);
            os.flush();
        } finally {
            close(os);
        }
    }

    /**
     * 响应json
     */
    public static void responseJson(boolean resultOk, HttpServletResponse response, HttpStatus status, String message, String data) throws IOException {
        PrintWriter os = null;
        try {
            os = response.getWriter();
            response.setStatus(resultOk ? HttpStatus.OK.value() : status.value());
            response.setContentType("application/json;charset=UTF-8");
            if (data != null) {
                os.write(String.format("{\"status\":%d,\"message\":\"%s\",\"data\":%s}", status.value(), message, data));
            } else {
                os.write(String.format("{\"status\":%d,\"message\":\"%s\"}", status.value(), message));
            }
            os.flush();
        } finally {
            close(os);
        }
    }

    /**
     * 关闭 cloneable
     */
    public static void close(Closeable cloneable) {
        if (null != cloneable) {
            try {
                cloneable.close();
            } catch (Exception e) {
                // e
            }
        }
    }
}
